package com.liuke.question1;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.liuke.question1.pojo.Result;
import com.liuke.question1.pojo.UriBean;
import com.liuke.question1.pojo.UriKeyMap;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.*;

/**
 * @Auther: 刘科
 * @Date: 2021/06/12/16:54
 * @Description:
 */
public class Question {
    private static String FILENAME = "access.log";
    private static String GETMETHOD = "GET";
    private static String POSTMETHOD = "POST";

    public Result analyzeAccess() {
        //返回的结果
        Result result = new Result();
        //读取文件数据
        List<UriBean> uriData = readData();
        if (uriData.isEmpty()) {
            return null;
        }
        //请求总数
        result.setRequestTotal(uriData.size());
        //最频繁的接口
        result.setFrequentRequest(frequentUriAnalyze(uriData));

        //方法请求量
        Map<String, Integer> methodCount = methodCountAnalyze(uriData);
        if (!methodCount.isEmpty()) {
            result.setGetMethodCount(methodCount.get(GETMETHOD));
            result.setPostMethodCount(methodCount.get(POSTMETHOD));
        }

        //分类统计
        result.setClassifyURI(classifyAnalyze(uriData));

        return result;
    }

    private Map<String, Set<String>> classifyAnalyze(List<UriBean> uriData) {
        Map<String, Set<String>> result = Maps.newHashMap();
        for (UriBean uriBean : uriData) {
            String uri = uriBean.getUri();
            String[] uriClassify = uri.split("/");
            String firstClassify = uriClassify[1];
            if (result.get(firstClassify) == null) {
                Set<String> childClassifySets = Sets.newHashSet();
                childClassifySets.add(uri);
                result.put(firstClassify, childClassifySets);
            } else {
                Set<String> childClassifySets = result.get(firstClassify);
                childClassifySets.add(uri);
                result.put(firstClassify, childClassifySets);
            }
        }
        return result;
    }

    private Map<String, Integer> methodCountAnalyze(List<UriBean> uriData) {
        Map<String, Integer> result = Maps.newHashMap();
        result.put(GETMETHOD, 0);
        result.put(POSTMETHOD, 0);
        for (UriBean uriBean : uriData) {
            if (uriBean.getMethod().equals(GETMETHOD)) {
                result.put(GETMETHOD, result.get(GETMETHOD) + 1);
            } else if (uriBean.getMethod().equals(POSTMETHOD)) {
                result.put(POSTMETHOD, result.get(POSTMETHOD) + 1);
            }
        }
        return result;
    }

    private List<UriKeyMap> frequentUriAnalyze(List<UriBean> uriData) {
        Map<String, Integer> tempCalculate = Maps.newHashMapWithExpectedSize(uriData.size() / 2);
        for (UriBean uriBean : uriData) {
            tempCalculate.merge(uriBean.getUri(), 1, Integer::sum);
        }
        List<UriKeyMap> uriKeyMapList = Lists.newArrayListWithCapacity(tempCalculate.size());
        Set<Map.Entry<String, Integer>> entrySet = tempCalculate.entrySet();
        for (Map.Entry<String, Integer> entry : entrySet) {
            UriKeyMap uriKeyMap = new UriKeyMap();
            uriKeyMap.setUri(entry.getKey());
            uriKeyMap.setCount(entry.getValue());
            uriKeyMapList.add(uriKeyMap);
        }
        uriKeyMapList.sort(new Comparator<UriKeyMap>() {
            @Override
            public int compare(UriKeyMap o1, UriKeyMap o2) {
                return o2.getCount() - o1.getCount();
            }
        });
        List<UriKeyMap> resul = Lists.newArrayListWithCapacity(10);
        for (int i = 0; i < 10; i++) {
            resul.add(uriKeyMapList.get(i));
        }
        return resul;
    }

    /**
     * 解析文本文件
     * @return
     */
    private List<UriBean> readData() {
        InputStreamReader read = null;
        ArrayList<UriBean> uriBeanArrayList = Lists.newArrayList();
        String filePath = Question.class.getClassLoader().getResource(FILENAME).getPath();
        File file = new File(filePath);
        try {
            read = new InputStreamReader(new FileInputStream(file));
            if (file.isFile() && file.exists()) {
                BufferedReader bufferedReader = new BufferedReader(read);
                String txt = null;
                while ((txt = bufferedReader.readLine()) != null) {
                    String[] splitStr = txt.split(" ");
                    UriBean uriBean = new UriBean();
                    uriBean.setMethod(splitStr[0]);
                    String[] uriSplit = splitStr[1].split("\\?");
                    uriBean.setUri(uriSplit[0]);
                    uriBeanArrayList.add(uriBean);
                }
            } else {
                throw new Exception("文件不存在");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (read != null) {
                try {
                    read.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return uriBeanArrayList;
    }
}
